﻿#include <iostream>

#include "criteria.h"

/*
 * C++设计模式之过滤器模式(Filter Pattern)
 * 允许开发人员使用不同的标准来过滤一组对象，通过逻辑运算以解耦的方式把它们连接起来。
 * 属于结构型模式，它结合多个标准来获得单一标准。
*/

int main()
{
    ///【1】 创建对象
    /// 6个男的
    ///          姓名        性别     体重   身高     外貌
    People boy1("boy1", People::MAN, 85.3, 187.5, "handsome");
    People boy2("boy2", People::MAN, 75.3, 169.5, "handsome");
    People boy3("boy3", People::MAN, 100.3, 175.5, "ugly");
    People boy4("boy4", People::MAN, 65.3, 178.5, "handsome");
    People boy5("boy5", People::MAN, 99.3, 166.5, "ugly");
    People boy6("boy6", People::MAN, 80.3, 175.5, "handsome");

    /// 6个女的
    People girl1("girl1", People::WOMAN, 85.3, 164.5, "handsome");
    People girl2("girl2", People::WOMAN, 60.3, 169.5, "handsome");
    People girl3("girl3", People::WOMAN, 55.3, 175.5, "ugly");
    People girl4("girl4", People::WOMAN, 55.3, 178.5, "handsome");
    People girl5("girl5", People::WOMAN, 50.3, 166.5, "ugly");
    People girl6("girl6", People::WOMAN, 56.3, 175.5, "handsome");

    std::list<People> peopleList;
    peopleList.push_back(boy1);
    peopleList.push_back(boy2);
    peopleList.push_back(boy3);
    peopleList.push_back(boy4);
    peopleList.push_back(boy5);
    peopleList.push_back(boy6);
    peopleList.push_back(girl1);
    peopleList.push_back(girl2);
    peopleList.push_back(girl3);
    peopleList.push_back(girl4);
    peopleList.push_back(girl5);
    peopleList.push_back(girl6);


    //单一过滤器
    std::shared_ptr<Criteria> height_filter(new Criteria_Higher(170,180));
    std::list<People> height_filter_people = height_filter->filter(peopleList);
    std::cout << "the list after height filter:" << std::endl;
    for (People &p : height_filter_people)
    {
        std::cout << p.show_me() << std::endl;
    }

    std::cout << "======================================="<< std::endl;
    //逻辑与&&过滤器
    std::shared_ptr<Criteria> face_filter(new Criteria_Handsome);
    And_Criteria and_filter;
    and_filter.add_criteria(height_filter);
    and_filter.add_criteria(face_filter);

    std::list<People> and_filter_boy = and_filter.filter(peopleList);
    std::cout << "the list people after and filter:" << std::endl;
    for (People &p : and_filter_boy)
    {
        std::cout << p.show_me() << std::endl;
    }


    std::cout << "======================================="<< std::endl;
    //逻辑或||过滤器
    Or_Criteria or_filter;
    or_filter.add_criteria(height_filter);
    or_filter.add_criteria(face_filter);
    std::list<People > or_filter_boy = or_filter.filter(peopleList);
    std::cout << "the list people after or filter:" << std::endl;
    for (People &p : or_filter_boy)
    {
        std::cout << p.show_me() << std::endl;
    }

    return 0;
}
